﻿#region Copyright & License

// Copyright © 2012 - 2013 François Chabot, Yves Dierick
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#endregion

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using Be.Stateless.Extensions;
using Be.Stateless.Linq.Extensions;

namespace Be.Stateless.BizTalk.Processes.Claim
{
	internal static class TokenAdapter
	{
		private static SqlConnection Connection
		{
			get { return new SqlConnection(ConfigurationManager.ConnectionStrings["TransientStateDb"].ConnectionString); }
		}

		internal static void ClearTokens()
		{
			using (var cnx = Connection)
			using (var cmd = new SqlCommand("DELETE FROM claim_Tokens", cnx))
			{
				cnx.Open();
				cmd.ExecuteNonQuery();
			}
		}

		internal static void InsertToken(string tokenUrl, string correlationToken)
		{
			InsertToken(tokenUrl, correlationToken, null, null, null, null);
		}

		internal static void InsertToken(string tokenUrl, string correlationToken, string messageType, string receiverName, string senderName)
		{
			InsertToken(tokenUrl, correlationToken, messageType, receiverName, senderName, null);
		}

		internal static void InsertToken(string tokenUrl, string correlationToken, string messageType, string receiverName, string senderName, string any)
		{
			const string cmdText = "INSERT claim_Tokens (Url, CorrelationToken, MessageType, ReceiverName, SenderName, [Any])"
				+ " VALUES(@url, @correlationToken, @messageType, @receiverName, @senderName, @any)";
			using (var cnx = Connection)
			using (var cmd = new SqlCommand(cmdText, cnx))
			{
				cmd.Parameters.AddWithValue("@url", tokenUrl);
				cmd.Parameters.AddWithValue("@correlationToken", correlationToken.IsNullOrEmpty() ? (object) DBNull.Value : correlationToken);
				cmd.Parameters.AddWithValue("@messageType", messageType.IsNullOrEmpty() ? (object) DBNull.Value : messageType);
				cmd.Parameters.AddWithValue("@receiverName", receiverName.IsNullOrEmpty() ? (object) DBNull.Value : receiverName);
				cmd.Parameters.AddWithValue("@senderName", senderName.IsNullOrEmpty() ? (object) DBNull.Value : senderName);
				cmd.Parameters.AddWithValue("@any", any.IsNullOrEmpty() ? (object) DBNull.Value : any.Trim());
				cnx.Open();
				cmd.ExecuteNonQuery();
			}
		}

		internal static void ReleaseToken(string tokenUrl)
		{
			ReleaseTokens(new[] { tokenUrl });
		}

		internal static void ReleaseTokens(string[] tokenUrls)
		{
			using (var cnx = Connection)
			using (var cmd = new SqlCommand("usp_claim_Release", cnx))
			{
				cmd.CommandType = CommandType.StoredProcedure;
				cmd.Parameters.AddWithValue("@url", string.Empty);
				cnx.Open();
				// ReSharper disable AccessToDisposedClosure
				tokenUrls.Each(
					tu => {
						cmd.Parameters["@url"].Value = tu;
						cmd.ExecuteNonQuery();
					});
				// ReSharper restore AccessToDisposedClosure
			}
		}

		internal static Dictionary<string, string> SelectTokens()
		{
			using (var cnx = Connection)
			using (var cmd = new SqlCommand("SELECT MessageType, Url FROM claim_Tokens", cnx))
			{
				cnx.Open();
				return cmd.ExecuteReader().Cast<IDataRecord>().ToDictionary(r => r["MessageType"].ToString(), r => r["Url"].ToString());
			}
		}
	}
}
